package sintacticAnalysis;

/**
 * Clasa ce se ocupa de analiza sintactica
 */
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;

import main.WriteFile;

import elements.Grammar;
import elements.Node;
import elements.Simbols;
import elements.Tree;
import elements.Vocabulary;

public class SintacticAnalysis {
	protected Grammar grammar;
	protected Vocabulary voc;
	protected static long time;
	protected BufferedWriter bwAux;

	public SintacticAnalysis() throws IOException {
		grammar = new Grammar();
		voc = new Vocabulary();
		time = 0;
		bwAux=new BufferedWriter(new FileWriter("auxiliar.txt"));
		bwAux.write("");
		bwAux.close();
	}

	/**
	 * returneaza tipul cuvantului (subiect, predicat, etc)
	 */
	public String returnType(String word) {
		if (voc.getName().contains(word))
			return "Subiect";
		if (voc.getActiuni().contains(word) || voc.getContext().contains(word))
			return "Predicat";
		if (voc.getTimp().contains(word))
			return "Complement de timp";
		if (voc.getInincaperi().contains(word))
			return "Complement de loc";
		if (voc.getIncaperi().contains(word) || voc.getStatice().contains(word)
				|| voc.getAparate().contains(word)
				|| voc.getSpalare().contains(word))
			return "Complement direct";
		if (voc.getSetari().contains(word) || voc.getCorp().contains(word))
			return "Complement direct";
		if (voc.getVreme().contains(word))
			return "Schimbare vreme";

		return null;
	}

	/**
	 * urmareste sa gaseasca un pattern pentru a determina daca scenariul foloseste
	 * gramatica corecta
	 */
	public boolean matchPattern(String[] tokens, int index)
	throws SintaxErrorException, IOException {
		String type;
		String pattern[] = new String[10];
		int k = 0;
		Tree<Simbols> tree = grammar.getTree();
		int sw=0;
		long swTime;
		elements.Node<Simbols> currentNode = tree.getRootElement();

		for (int i = 0; i < tokens.length; i++) {

			type = returnType(tokens[i]);
			if (type == null)
				throw new SintaxErrorException("Incorrect word at line "
						+ index + " : " + tokens[i] + "\n");

			if (i != 0 && type.equals(voc.getName()))
				type = "Complement direct";
			if (type == "Complement de timp")
				if (!tokens[i + 1].contains(":"))
					throw new SintaxErrorException(
							"CT not followed by hour at line " + index + "\n");
				else {
					i++;
					if (sw == 0) {
						sw = 1;
						swTime = convertHour(tokens[i]);
						if (swTime - time < 0)
							throw new SintaxErrorException(
									"Actions not in chronological order at line "
									+ index + "\n");
						time=swTime;

					}
				}
			if (voc.getSetari().contains(tokens[i]))
				if (!voc.getIntensitate().contains(tokens[i + 1]))
					throw new SintaxErrorException(
							"Setting not followed by intensity at line "
							+ index + "\n");
				else
					i++;

			ArrayList<Node<Simbols>> al = currentNode.getChildren();

			int aux = 0;
			for (Node<Simbols> e : al) {
				if (((Simbols) e.getData()).getSimbol().equals(type)) {
					aux = 1;
					pattern[k++] = type;
					if (i == tokens.length - 1
							&& ((Simbols) e.getData()).getTerminal() == 0)
						throw new SintaxErrorException(
								"Incorrect word number/order at line: " + index
								+ "\n");
					currentNode = currentNode.getChild(e.getData());
				}
			}
			if (aux == 0)
				throw new SintaxErrorException("Incorrect word order at line: "
						+ index + "\n");
		}

		/**
		 * scrie in fisierul auxiliar
		 */
		bwAux=new BufferedWriter(new FileWriter("auxiliar.txt",true));
		if (pattern[0].equals("Schimbare vreme"))
			for (int i=0; i<tokens.length; i++)
				if(tokens[i].equals("la ora"))
					continue;
				else 
					bwAux.append(tokens[i]+" ");
		else
			if(pattern[0]=="Predicat")
				for (int i = 0; i < tokens.length; i++)
					if((tokens[i].equals("la ora"))||(tokens[i].equals("de la ora")))
						continue;
					else 
						if (tokens[i].contains(" ")&&(!tokens[i].startsWith("aer"))&&(!tokens[i].startsWith("masina")))
							bwAux.append(tokens[i].substring(3)+" ");
						else
							bwAux.append(tokens[i]+" ");
			else {
				if (tokens[1].contains(" ")&&tokens[1].startsWith("se"))
					bwAux.append(tokens[1].substring(3)+" ");
				else
					if (tokens[1].contains("WC"))
						bwAux.append("merge_la_WC ");
					else
						bwAux.append(tokens[1]+" ");
				bwAux.append(tokens[0]+" ");
				for (int i = 2; i < tokens.length; i++)
					if((tokens[i].equals("la ora"))||(tokens[i].equals("de la ora")))
						continue;
					else 
						if (tokens[i].contains(" ")&&(!tokens[i].startsWith("aer"))&&(!tokens[i].startsWith("masina")))
							bwAux.append(tokens[i].substring(3)+" ");
						else
							bwAux.append(tokens[i]+" ");
			}
		bwAux.newLine();
		bwAux.close();
		return true;
	}

	private long convertHour(String hour) {
		String tokens[] = null;
		tokens = hour.split(":");
		return 3600 * Integer.parseInt(tokens[0]) + 60
		* (Integer.parseInt(tokens[1])) + Integer.parseInt(tokens[2]);
	}
}
